<?php


namespace app\admin\service;


use app\admin\model\AdModel;
use app\admin\model\ArticleModel;
use app\admin\model\StatisticsModel;
use app\Exception\DbException;
use app\utils\redis\RedisCache;
use think\db\BaseQuery;

class StatisticsService
{
    /**
     * 获取文章点击详情列表
     * @param array $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getArticleStatisticsDetails(array $param) {
        [$ids, $id_num] = $this->getArticleOrAdIds($param['id'], 'article');
        return $this->getArticleStatisticsByIds($param, $ids, $id_num);
    }

    /**
     * 获取广告统计
     * @param array $param
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getAdStatisticsDetails(array $param) {
        [$id_num_arr, $ids] = $this->getArticleOrAdIds($param['id'], 'ad');
        return $this->getAdStatisticsByIds($param, $ids, $id_num_arr);
    }

    /**
     * 查找当天redis中的文章点击数
     * @param array $param
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function getTodayArticleStatistics(array $param) {
        [$id_num_arr, $_, $ids] = (new TimeTaskService())->getTodayArticleStatisticsByRedis();
        if(count($ids)===0){
            return nullDataPaginateArr();
        }
        $new_id_num_arr = ($this->jsonToIdArrAndIdNumArr($id_num_arr))[1];
        return $this->getArticleStatisticsByIds($param, $ids, $new_id_num_arr);
    }

    /**
     * 查找当天redis中的广告点击数
     * @param array $param
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function getTodayAdStatistics(array $param) {
        [$id_num_arr, $_, $ids] = (new TimeTaskService())->getTodayAdStatisticsByRedis();
        if(count($ids)===0){
            return nullDataPaginateArr();
        }
        $new_id_num_arr = ($this->jsonToIdArrAndIdNumArr($id_num_arr))[1];
        return $this->getAdStatisticsByIds($param, $ids, $new_id_num_arr);
    }

    /**
     * 通过id集合获取对应的文章详情
     * @param array $param
     * @param array $ids id集合
     * @param array $id_num id=>当天点击数集合
     * @return array
     * @throws \think\db\exception\DbException
     */
    private function getArticleStatisticsByIds(array $param, array $ids, array $id_num) {
        $articleModel = new ArticleModel();
        $condition = [
            'id' => ['id', 'in', $ids],
        ];
        $hidden = [
            'article_content', 'article_originate', 'article_status', 'article_sticky',
            'update_time',
        ];
        $result = $articleModel->withPaginate(
            ['articleCategory' => function (BaseQuery $query) {
                $query->visible(['id', 'category_name']);
            }, 'articleTag' => function (BaseQuery $query) {
            }], $param, $condition, $hidden, [], [], ['id']
        );
        // 新的数据，添加多一个属性
        $new_lists = [];
        foreach ($result['lists'] as $article) {
            $article['today_num'] = $id_num[$article['id']];
            array_push($new_lists, $article);
        }
        $result['lists'] = $new_lists;
        return $result;
    }

    /**
     * 通过id集合获取对应的广告
     * @param array $param 通过校验参数
     * @param array $ids id集合
     * @param array $id_num id=>当天点击量
     * @return array
     * @throws \think\db\exception\DbException
     */
    private function getAdStatisticsByIds(array $param, array $ids, array $id_num) {
        $adModel = new AdModel();
        $condition = [
            'id' => ['id', 'in', $ids],
        ];
        $result = $adModel->toPaginate($param, $condition, [], ['id']);
        $new_lists = [];
        foreach ($result['lists'] as $article) {
            $article['today_num'] = $id_num[$article['id']];
            array_push($new_lists, $article);
        }
        $result['lists'] = $new_lists;
        return $result;
    }

    /**
     * 通过id获取文章或者广告id集合
     * @param int $id
     * @param string $type
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function getArticleOrAdIds(int $id, string $type) {
        $statisticsResult = StatisticsModel::find($id);
        if(!$statisticsResult){
            throw new DbException('id不存在');
        }
        return $type==='article'
            ?$this->jsonToIdArrAndIdNumArr($statisticsResult->today_article_num)
            :$this->jsonToIdArrAndIdNumArr($statisticsResult->today_ad_num);
    }

    /**
     * 通过json转成id集合和id_num集合
     * @param string|array $json
     * @return array[]
     */
    private function jsonToIdArrAndIdNumArr($json) {
        $arr = $json;
        if(is_string($json)){
            $arr = json_decode($json, true);
        }
        // 文章的ID集合
        $ids = [];
        // ID对应的点击数
        $id_num = [];
        foreach ($arr as $item) {
            array_push($ids,$item['id']);
            $id_num[$item['id']] = $item['num'];
        }
        return [$ids, $id_num];
    }
}